css: Add more features to font-size code
authorBenjamin Otte <otte@redhat.com>
Sat, 1 Dec 2012 13:00:24 +0000 (14:00 +0100)
committerBenjamin Otte <otte@redhat.com>
Sat, 1 Dec 2012 13:00:24 +0000 (14:00 +0100)
We now support the keywords (like xx-small, medium, larger, smaller...)
and I've changed the default value to be "medium".

This required some shuffling of the "get default font size" code. But
all is well now.

gtk/gtkcssenumvalue.c
gtk/gtkcssenumvalueprivate.h
gtk/gtkcssinitialvalue.c
gtk/gtkcssstylepropertyimpl.c
gtk/gtkcsstypesprivate.h

index b739567970092e472b287184b3642aa02ea9a279..e81b7b2d8a6c2410aaf04b7b558a16cc8cdf51d1 100644 (file)
@@ -19,7 +19,9 @@
 
 #include "gtkcssenumvalueprivate.h"
 
-#include "gtkstylepropertyprivate.h"
+#include "gtkcsscomputedvaluesprivate.h"
+#include "gtkcssnumbervalueprivate.h"
+#include "gtkstyleproviderprivate.h"
 
 /* repeated API */
 
@@ -124,6 +126,149 @@ _gtk_css_border_style_value_get (const GtkCssValue *value)
   return value->value;
 }
 
+/* GtkCssFontSize */
+
+/* XXX: Kinda bad to have that machinery here, nobody expects vital font
+ * size code to appear in gtkcssvalueenum.c.
+ */
+#define DEFAULT_FONT_SIZE 10
+
+static double
+get_default_font_size (GtkStyleProviderPrivate *provider)
+{
+  GtkSettings *settings;
+  PangoFontDescription *description;
+  char *font_name;
+  double font_size;
+
+  settings = _gtk_style_provider_private_get_settings (provider);
+  if (settings == NULL)
+    return DEFAULT_FONT_SIZE;
+  
+  g_object_get (settings, "gtk-font-name", &font_name, NULL);
+  description = pango_font_description_from_string (font_name);
+  g_free (font_name);
+  if (description == NULL)
+    return DEFAULT_FONT_SIZE;
+
+  if (pango_font_description_get_set_fields (description) & PANGO_FONT_MASK_SIZE)
+    font_size = (double) pango_font_description_get_size (description) / PANGO_SCALE;
+  else
+    font_size = DEFAULT_FONT_SIZE;
+
+  pango_font_description_free (description);
+  return font_size;
+}
+
+static GtkCssValue *
+gtk_css_value_font_size_compute (GtkCssValue             *value,
+                                 guint                    property_id,
+                                 GtkStyleProviderPrivate *provider,
+                                 GtkCssComputedValues    *values,
+                                 GtkCssComputedValues    *parent_values,
+                                 GtkCssDependencies      *dependencies)
+{
+  double font_size;
+
+  switch (value->value)
+    {
+    case GTK_CSS_FONT_SIZE_XX_SMALL:
+      font_size = get_default_font_size (provider) * 3. / 5;
+      break;
+    case GTK_CSS_FONT_SIZE_X_SMALL:
+      font_size = get_default_font_size (provider) * 3. / 4;
+      break;
+    case GTK_CSS_FONT_SIZE_SMALL:
+      font_size = get_default_font_size (provider) * 8. / 9;
+      break;
+    default:
+      g_assert_not_reached ();
+      /* fall thru */
+    case GTK_CSS_FONT_SIZE_MEDIUM:
+      font_size = get_default_font_size (provider);
+      break;
+    case GTK_CSS_FONT_SIZE_LARGE:
+      font_size = get_default_font_size (provider) * 6. / 5;
+      break;
+    case GTK_CSS_FONT_SIZE_X_LARGE:
+      font_size = get_default_font_size (provider) * 3. / 2;
+      break;
+    case GTK_CSS_FONT_SIZE_XX_LARGE:
+      font_size = get_default_font_size (provider) * 2;
+      break;
+    case GTK_CSS_FONT_SIZE_SMALLER:
+      if (parent_values)
+        font_size = _gtk_css_number_value_get (_gtk_css_computed_values_get_value (parent_values, GTK_CSS_PROPERTY_FONT_SIZE), 100);
+      else
+        font_size = get_default_font_size (provider);
+      /* XXX: This is what WebKit does... */
+      font_size *= 1.2;
+      break;
+    case GTK_CSS_FONT_SIZE_LARGER:
+      if (parent_values)
+        font_size = _gtk_css_number_value_get (_gtk_css_computed_values_get_value (parent_values, GTK_CSS_PROPERTY_FONT_SIZE), 100);
+      else
+        font_size = get_default_font_size (provider);
+      /* XXX: This is what WebKit does... */
+      font_size /= 1.2;
+      break;
+  }
+
+  return _gtk_css_number_value_new (font_size, GTK_CSS_PX);
+}
+
+static const GtkCssValueClass GTK_CSS_VALUE_FONT_SIZE = {
+  gtk_css_value_enum_free,
+  gtk_css_value_font_size_compute,
+  gtk_css_value_enum_equal,
+  gtk_css_value_enum_transition,
+  gtk_css_value_enum_print
+};
+
+static GtkCssValue font_size_values[] = {
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_XX_SMALL, "xx-small" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_X_SMALL, "x-small" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_SMALL, "small" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_MEDIUM, "medium" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_LARGE, "large" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_X_LARGE, "x-large" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_XX_LARGE, "xx-large" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_SMALLER, "smaller" },
+  { &GTK_CSS_VALUE_FONT_SIZE, 1, GTK_CSS_FONT_SIZE_LARGER, "larger" },
+};
+
+GtkCssValue *
+_gtk_css_font_size_value_new (GtkCssFontSize font_size)
+{
+  g_return_val_if_fail (font_size < G_N_ELEMENTS (font_size_values), NULL);
+
+  return _gtk_css_value_ref (&font_size_values[font_size]);
+}
+
+GtkCssValue *
+_gtk_css_font_size_value_try_parse (GtkCssParser *parser)
+{
+  guint i;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  for (i = 0; i < G_N_ELEMENTS (font_size_values); i++)
+    {
+      if (_gtk_css_parser_try (parser, font_size_values[i].name, TRUE))
+        return _gtk_css_value_ref (&font_size_values[i]);
+    }
+
+  return NULL;
+}
+
+GtkCssFontSize
+_gtk_css_font_size_value_get (const GtkCssValue *value)
+{
+  g_return_val_if_fail (value->class == &GTK_CSS_VALUE_FONT_SIZE, GTK_CSS_FONT_SIZE_MEDIUM);
+
+  return value->value;
+}
+
 /* PangoStyle */
 
 static const GtkCssValueClass GTK_CSS_VALUE_FONT_STYLE = {
index 09a9d671cf628b4a7f375501bb4dddb77476de8d..56b6ea3c3b9a297db0e5aacad7712f145bee590f 100644 (file)
@@ -31,6 +31,10 @@ GtkCssValue *   _gtk_css_border_style_value_new       (GtkBorderStyle     border
 GtkCssValue *   _gtk_css_border_style_value_try_parse (GtkCssParser      *parser);
 GtkBorderStyle  _gtk_css_border_style_value_get       (const GtkCssValue *value);
 
+GtkCssValue *   _gtk_css_font_size_value_new          (GtkCssFontSize     size);
+GtkCssValue *   _gtk_css_font_size_value_try_parse    (GtkCssParser      *parser);
+GtkCssFontSize  _gtk_css_font_size_value_get          (const GtkCssValue *value);
+
 GtkCssValue *   _gtk_css_font_style_value_new         (PangoStyle         style);
 GtkCssValue *   _gtk_css_font_style_value_try_parse   (GtkCssParser      *parser);
 PangoStyle      _gtk_css_font_style_value_get         (const GtkCssValue *value);
index b70b7941122cd8e6ff9f5749c968253c798075e6..427044d57466f9eeed0f5dc13b1e437a74b18b6c 100644 (file)
@@ -73,31 +73,6 @@ gtk_css_value_initial_compute (GtkCssValue             *value,
         }
       break;
 
-    case GTK_CSS_PROPERTY_FONT_SIZE:
-      settings = _gtk_style_provider_private_get_settings (provider);
-      if (settings)
-        {
-          PangoFontDescription *description;
-          char *font_name;
-          GtkCssValue *value;
-
-          g_object_get (settings, "gtk-font-name", &font_name, NULL);
-          description = pango_font_description_from_string (font_name);
-          g_free (font_name);
-          if (description == NULL)
-            break;
-
-          if (pango_font_description_get_set_fields (description) & PANGO_FONT_MASK_SIZE)
-            {
-              value = _gtk_css_number_value_new ((double) pango_font_description_get_size (description) / PANGO_SCALE, GTK_CSS_PX);
-              pango_font_description_free (description);
-              return value;
-            }
-          pango_font_description_free (description);
-        }
-      break;
-
     default:
       break;
     }
index e1e19b274283191bddc28668c1f98999bd951581..bd22a7c1d72df2698e1e53bb4b230dccf57450b2 100644 (file)
@@ -648,8 +648,13 @@ static GtkCssValue *
 font_size_parse (GtkCssStyleProperty *property,
                  GtkCssParser        *parser)
 {
+  GtkCssValue *value;
   gdouble d;
 
+  value = _gtk_css_font_size_value_try_parse (parser);
+  if (value)
+    return value;
+
   if (!_gtk_css_parser_try_double (parser, &d))
     {
       _gtk_css_parser_error (parser, "Expected a number");
@@ -878,8 +883,7 @@ _gtk_css_style_property_init_properties (void)
                                           font_size_parse,
                                           query_length_as_double,
                                           assign_length_from_double,
-                                          /* XXX: This should be 'normal' */
-                                          _gtk_css_number_value_new (10.0, GTK_CSS_PX));
+                                          _gtk_css_font_size_value_new (GTK_CSS_FONT_SIZE_MEDIUM));
 
   /* properties that aren't referenced when computing values
    * start here */
index ab360ef7d5c9cf110f7dc18b272f2fce33e10e05..f2130de481dc7ce35967166920607d2f9d8d99bc 100644 (file)
@@ -161,6 +161,20 @@ typedef enum /*< skip >*/ {
   GTK_CSS_FILL_BOTH
 } GtkCssFillMode;
 
+typedef enum /*< skip >*/ {
+  /* absolute font sizes */
+  GTK_CSS_FONT_SIZE_XX_SMALL,
+  GTK_CSS_FONT_SIZE_X_SMALL,
+  GTK_CSS_FONT_SIZE_SMALL,
+  GTK_CSS_FONT_SIZE_MEDIUM,
+  GTK_CSS_FONT_SIZE_LARGE,
+  GTK_CSS_FONT_SIZE_X_LARGE,
+  GTK_CSS_FONT_SIZE_XX_LARGE,
+  /* relative font sizes */
+  GTK_CSS_FONT_SIZE_SMALLER,
+  GTK_CSS_FONT_SIZE_LARGER
+} GtkCssFontSize;
+
 /* for the order in arrays */
 typedef enum /*< skip >*/ {
   GTK_CSS_TOP,